package com.flong.spring.annotation;

import com.flong.spring.bean.Color;
import com.flong.spring.bean.ColorFactoryBean;
import com.flong.spring.bean.Red;
import com.flong.spring.bean.Student;
import com.flong.spring.conditional.LinuxConditional;
import com.flong.spring.conditional.MyImportBeanDefinitionRegistrar;
import com.flong.spring.conditional.MyImportSelector;
import com.flong.spring.conditional.WindowConditional;
import com.flong.spring.filter.MyFilter;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;
import org.springframework.web.context.WebApplicationContext;

/**
 * @Author:liangjl
 * @Date: 2020/6/10-18:50
 * @Eamil:jilongliang@sina.com
 * @Description: -------------------------------------------
 *
 * Conditional 可以放在类的上面，也可以放在方法上面
 *
 * Import 给容器中注册组件
 * 1、包扫描+组件标注注解(@Controller/@Servcie/@Repository/@Component)
 * 2、@Bean[导入的第三方包里面的组件]
 * 3、@Import[快速给容器导入一个组件]
 *   3.1、@Import(要导入到容器中的组件)；容器中就会自动注册这个组件，id默认是全类名
 *   3.2、ImportSelector 返回需要导入的组件的全类名的数组
 *   3.3、ImportBeanDefinitionRegistrar 手动注册Bean容器中
 * 4、使用Spring提供的 @see `FactoryBean`(工厂Bean)
 *   4.1、默认获取到是工厂bean调用的getObject创建的对象
 *   4.2、要获取工厂Bean本身，我们需要给id前面加一个&比如（&colorFactoryBean）
 *@see BeanFactory
 */
@Configuration
@Conditional({WindowConditional.class})
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class StudentConfig2 {

    /**
     * @return
     * @see ConfigurableBeanFactory
     * @see WebApplicationContext
     * prototype 多实例,ioc容器启动并不会去调用方法创建对象放在容器中，每次获取的时候才会调用方法创建对象
     * singleton 单例，ioc容器启动就会调用方法创建对象放到ioc容器中，以后每次获取就是直接从容器(map.get)中获取
     * request 同一次请求创建一个实列
     * session 同一个session创建一个实例
     * <p>
     * 懒加载
     * 单实例bean,默认在容器启动的时候创建对象
     * 懒加载：容器启动不创建对象，第一次使用(获取)bean创建对象，并初始化
     */
    //@Scope(value = "prototype")
    @Lazy
    @Bean(value = "student1")
    public Student getStudent() {
        System.out.println("ioc容器创建启动");
        return Student.builder().age(90).userName("一灯大师").build();
    }

    @Bean("bill")
    //@Conditional({WindowConditional.class})
    public Student getStudent1() {
        return Student.builder().age(80).userName("比尔盖茨").build();
    }

    @Bean("linus")
    @Conditional({LinuxConditional.class})
    public Student getStudent2() {
        return Student.builder().age(60).userName("利纳斯").build();
    }


    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }
}
